#pragma once
//reflection.h
//c++实现反射 
#include<map>
using namespace std;
 
//定义函数指针，用于指向创建类实例的回调函数. 
typedef void* (*PTRCreateObject)(void);
 
//工厂类的定义（单例模式） 
class ClassFactory{
private:
	ClassFactory(){};										//构造函数私有化
	~ClassFactory(){}; 
	map<string,PTRCreateObject> m_classMap;					//储存反射类 
public:
	void* getClassByName(string className);					//反射class 
	void registClass(string name,PTRCreateObject method);	//注册需要反射的类 
	static ClassFactory& getInstance(); 					//返回工厂类实例 
}; 
 
//@brief:获取工厂类的单个实例对象  
ClassFactory& ClassFactory::getInstance(){
	static ClassFactory sLo_factory;
	return sLo_factory;
} 
 
//@brief:通过类名称字符串获取类的实例
void* ClassFactory::getClassByName(string className){
	auto iter = m_classMap.find(className);
	if(iter != m_classMap.end()){
		return iter->second();
	}else{
		throw new string("无此类名");
		return nullptr;
	}
}
 
//@brief:将给定的类名称字符串和对应的创建类对象的函数保存到map中   
void ClassFactory::registClass(string name,PTRCreateObject method){
	m_classMap.insert(pair<string,PTRCreateObject>(name,method));
}
 
//注册方法类，因为全局域不能直接调用函数，只能间接通过类来实现调用注册方法
class RegisterAction {
public:
    RegisterAction(string className, PTRCreateObject ptrCreateFn) {
        ClassFactory::getInstance().registClass(className, ptrCreateFn);
    }
};
 
#define REGISTER(className)\
	className* objectCreator_##className(){	\
		return new className;\
	} \
	RegisterAction register_##className(#className,(PTRCreateObject)objectCreator_##className);
 
 